<?php

namespace app\admin\controller;
use think\captcha\facade\Captcha;
use think\exception\ValidateException;
use think\facade\Db;
use app\admin\model\AdminToken as AdminTokenModel;
use app\admin\model\Admin\Role as RoleModel;
use app\admin\model\Admin\Dept as DeptModel;

class Login extends Admin
{

    /**
     * 用户登录
     * @return \think\response\Json
     */
    public function index(){
		$postField = 'username,password,verify,key';
		$data = $this->request->only(explode(',',$postField),'post',null);
		if(empty($data['username'])) throw new ValidateException('请输入验证码');
		if(empty($data['password'])) throw new ValidateException('请输入密码');
		// 登录是否启用图片验证码
		$verify_status = !is_null(config('rds.verify_status')) ? config('rds.verify_status') : true;
		// 如果启用图片验证码则检查验证码
		if($verify_status){
			// 检查是否输入验证码
		    if(empty($data['verify'])) throw new ValidateException('请输入验证码');
            // 验证输入的验证码是否正确
            $captcha = cache('ADMIN_LOGIN_VERIFY_'.$data['key']);
			if($captcha && password_verify(mb_strtolower($data['verify'],'UTF-8'),$captcha)){
			    cache('ADMIN_LOGIN_VERIFY_'.$data['key'],null);
            } else {
                throw new ValidateException('验证码错误');
            }
		}
		// 检查用户
		$res = $this->checkLogin($data);
		if($res){
            return json(['status'=>200,'token'=>$this->setToken($res)]);
		}
    }

    /**
     * 获取验证码和匿名信息
     * @return \think\response\Json
     */
    public function verify(){
        $data['rememberMe'] = true;
        // 生成验证码
        $key = uniqid(rand(00000,99999), true);
        $rs = Captcha::create();
        $base64_image = "data:image/png;base64," . base64_encode($rs->getData());
        $captcha = session('captcha.key');
        cache('ADMIN_LOGIN_VERIFY_'.$key,$captcha);
        $data['data'] = [
            'key'   => $key,
            'img'   => $base64_image,
        ];
        // 基本配置中读取的内容
        $data['site_title'] = config('admin_config.site_title');
        $data['site_subtitle'] = config('admin_config.site_subtitle');
        $data['site_note'] = config('admin_config.site_note');
        $data['copyright'] = config('admin_config.copyright');
        // 登录成功后跳转到的页面
        $data['success_url'] = (string)url('admin/Home/index');
        // 是否显示验证码
        $data['verify_status'] = !is_null(config('rds.verify_status')) ? config('rds.verify_status') : true;
        $data['status'] = 200;
        return json($data);
    }

    /**
     * 验证登录
     * @param $data
     * @return array|mixed|Db|\think\Model
     */
    private function checkLogin($data){
        try {
            $where['username'] = $data['username'];
            $where['password']  = md5($data['password'].config('rds.password_secrect'));
            // 查询用户名和密码是否匹配
            $userInfo = \think\facade\Db::name('admin_user')->where($where)->find();
            if(empty($userInfo)){
                throw new ValidateException("用户名或者密码错误，请联系管理员");
            }
            // 获取用户所属角色的信息
            $roleIds = explode(',',$userInfo['role_id']);
            $roleList = \think\facade\Db::name('admin_role')->where(['role_id'=>$roleIds])->select()->toArray();
            $roleStatus = array_column($roleList,'status');
            if(in_array('0',$roleStatus)){
                throw new ValidateException("所属角色被禁用，请联系管理员");
            }
            // 获取用户所属部门
            $deptInfo = \think\facade\Db::name('admin_dept')->where(['dept_id'=>$userInfo['dept_id']])->find();
            if($deptInfo['status'] == '0'){
                throw new ValidateException("所属部门被禁用，请联系管理员");
            }
            $userInfo['roleList'] = $roleList;
            $userInfo['detpInfo'] = $deptInfo;
            $userInfo['pid'] = $deptInfo['pid'];
        } catch (\Exception $e){
            throw new ValidateException($e->getMessage());
        }
        event('LoginLog',$this->userInfo);	//写入登录日志
        return $userInfo;
    }


    /**
     * 获取用户信息 菜单信息 以及菜单对应的组件
     * @return \think\response\Json
     */
    public function getUserInfo(){
        try {
            // 查到用户所属的所有角色，并把赋予的菜单权限都组织到一个数组中去重
            $roleIds = explode(',',$this->userInfo['role_id']);
            $roleList = \think\facade\Db::name('admin_role')->where(['role_id'=>$roleIds])->select()->toArray();
            $accessArray = array_column($roleList,'access');
            $accessList = array_unique(explode(',',implode(',',$accessArray)));
            // 获得此用户所属角色的所有授权菜单
            $menu = $this->getMyMenus($roleIds,$accessList,$this->getTotalMenus());
            $components = $this->getComponents($menu);
            //如果是超级管理员则把下面两个组件挂载上
            if(in_array(1,$roleIds)){
                $fieldComponents = [
                    'name'=>'Field',
                    'path'=> (string)url('admin/Field/index'),
                    'meta'=>[
                        'title'=>'字段管理',
                    ],
                    'component_path'=>'admin/sys/field/Index.vue'
                ];
                $actionComponents = [
                    'name'=>'Action',
                    'path'=> (string)url('admin/Action/index'),
                    'meta'=>[
                        'title'=>'方法管理',
                    ],
                    'component_path'=>'admin/sys/action/Index.vue'
                ];
                array_push($components,$fieldComponents,$actionComponents);
            }
            $components = array_merge($components,$this->getHiddenComponents($roleIds,$accessList)); 	//挂载菜单隐藏 但是定义了的组件
            $userInfo = $this->userInfo;
            $userInfo['site_title']  = config('admin_config.site_title');
            $userInfo['site_logo'] = config('admin_config.site_logo');
            $userInfo['show_notice'] = !is_null(config('rds.show_notice')) ? config('rds.show_notice') : true;	//是否显示消息提示按钮
            $data['status'] = 200;
            $data['menu'] = $menu;
            $data['components'] = $components;
            $data['actions'] = $accessList;
            $data['data'] = $userInfo;
        } catch (\Exception $e){
            throw new ValidateException($e->getMessage());
        }

        return json($data);
    }


    /**
     * 获取当前用户所有的菜单
     * @param $totalMenus
     * @return array
     */
    private function getMyMenus($roleIds,$accessList,$totalMenus){
        try {
            // 当前用户的所属角色编号字符串，如果包含1，则返回所有菜单
            if(in_array(1,$roleIds)){
                return $totalMenus;
            }
            // 将全部菜单分别与用户所拥有的角色中的菜单做对比，选出用户被授予的
            $tree = [];
            foreach($totalMenus as $key => $val){
                if(in_array($val['name'], $accessList, true)){
                    $tree[$key] = array_merge($val,['children'=>$this->getMyMenus($roleIds,$accessList,$val['children'])]);
                }
            }
        } catch (\Exception $e){
            throw new ValidateException($e->getMessage());
        }
        return $tree;
    }


    /**
     * 登出
     * @return \think\response\Json
     */
    public function logout(){
		$token = $this->request->header('Authorization');
		AdminTokenModel::where('token',$token)->delete();
        return json(['status'=>200]);
    }


}
